package com.je.gateway.security;

import org.owasp.esapi.ESAPI;

import java.util.regex.Pattern;

public class PlatformScriptInputSecurityHandler implements  PlatformInputSecurityHandler<String> {
    /**
     * 避免iframe 标签
     */
    Pattern iframePattern = Pattern.compile("<iframe src=(.*?)>", Pattern.CASE_INSENSITIVE);

    /**
     * 避免script 标签
     */
    Pattern scriptPattern = Pattern.compile("<script>(.*?)</script>", Pattern.CASE_INSENSITIVE);

    /**
     * 避免src形式的表达式
     */
    Pattern scriptSrcPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    /**
     * 删除单个的 </script> 标签
     */
    Pattern scriptEndPattern = Pattern.compile("</script>", Pattern.CASE_INSENSITIVE);

    /**
     * 删除单个的<script ...> 标签
     */
    Pattern scriptSinglePattern = Pattern.compile("<script(.*?)>", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    /**
     * 避免 eval(...) 形式表达式
     */
    Pattern scriptEvalPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    /**
     * 避免 e­xpression(...) 表达式
     */
    Pattern scriptExpressionPattern = Pattern.compile("expression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    /**
     * 避免 javascript: 表达式
     */
    Pattern scriptJavaScriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE);

    /**
     * 避免 vbscript: 表达式
     */
    Pattern scriptVbScriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE);

    /**
     * 避免 οnlοad= 表达式
     */
    Pattern scriptOnloadPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    /**
     * 避免 onClickXX= 表达式
     */
    Pattern scriptOnClickXXPattern = Pattern.compile("onClick.*(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    /**
     * 避免 onRemoveXX= 表达式
     */
    Pattern scriptOnRemovePattern = Pattern.compile("onRemove.*(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);

    @Override
    public Boolean valid(String name, String value)  {
        //进行标准化，防止脚本攻击
        value = ESAPI.encoder().canonicalize(value);
        return (scriptPattern.matcher(value).find() || scriptSrcPattern.matcher(value).find()
                || scriptEndPattern.matcher(value).find() || scriptSinglePattern.matcher(value).find()
                || scriptEvalPattern.matcher(value).find() || scriptExpressionPattern.matcher(value).find()
                || scriptJavaScriptPattern.matcher(value).find() || scriptVbScriptPattern.matcher(value).find()
                || scriptOnloadPattern.matcher(value).find() || scriptOnClickXXPattern.matcher(value).find()
                || scriptOnRemovePattern.matcher(value).find() || iframePattern.matcher(value).find());
    }
}
